package br.ufrj.ppgi.infovis.mtgraph;

import org.mt4j.components.MTComponent;
import org.mt4j.components.visibleComponents.shapes.MTLine;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
import org.mt4j.util.math.Vertex;

import br.ufrj.ppgi.infovis.util.UnorderedPair;

/**
 * @author Ewoud van Pareren
 * 
 * A simple edge class.
 * 
 */
public class GraphEdge {
	
	/*
	 * The 'parent' node of this edge.
	 */
	//Node parent; // The Node above this edge
	//Node child; // The Node below this edge
	
	private UnorderedPair<GraphNode> nodes;
	private Graph graph;
	
	MTLine component;
	
	
	public GraphEdge(GraphNode a, GraphNode b) {
		nodes = new UnorderedPair<GraphNode>(a, b);
		graph = a.getGraph();
	}

	public GraphNode[] getNodes(){
		return nodes.getElements();
	}
	
	
	public void setComponent() {			
		if ((getGraph() == null) || (getGraph().getGraphScene() == null)) {
			throw new RuntimeException("Cannot set line component: no graph or graphscene to use");
		}
		setComponent(getGraph().getGraphScene().makeDefaultLine());
	}
	

	public void setComponent(MTLine in) {
		if (((getGraph() == null) || (getGraph().getGraphScene() == null)) && (in != null))
			throw new RuntimeException("Cannot set line component: no graph or graphscene to use");
		
		if (component != null) {
			getGraph().getGraphScene().removeChild(component); //TODO reorganizar
			component.destroy();
		}
		
		component = in;
		
		if (getGraph() != null) getGraph().invalidate();
	}
	
	/**
	 * Get the current component.
	 * 
	 * @return the current component, may be null if no component is set
	 */
	public MTLine getComponent() {
		return component;
	}
	
	
	/**
	 * This updates the lines.
	 * Note that this is called from update, and from any movement of connected nodes.
	 * 
	 * Any application that moves Node components outside of the framework should call
	 * this method to update the lines.
	 */
	public void updateLines() {
		GraphNode[] nodes = this.getNodes();
		GraphNode a = nodes[0];
		GraphNode b = nodes[1];
		
		//if (component.getParent() != null)
			//System.out.println("parent da edge: " + component.getParent().getClass());
		if (a != null && a.getComponent() != null &&
				b != null && b.getComponent() != null && component != null) {
			Vertex[] newLine = new Vertex[2];
			newLine[0] = new Vertex(a.getComponent().getCenterPointGlobal());
			newLine[1] = new Vertex(b.getComponent().getCenterPointGlobal());
			//newLine[0] = new Vertex(a.getComponent().getCenterPointLocal());
			//newLine[1] = new Vertex(b.getComponent().getCenterPointLocal());
			//if (a.getComponent().getParent() != null)
			//	System.out.println("parent do vertice a: " + a.getComponent().getParent().getClass());
			
			//if (b.getComponent().getParent() != null) 
			//	System.out.println("parent do vertice b: " + b.getComponent().getParent().getClass());
			component.setVertices(newLine);
			
		}

	}
	
	
	Graph getGraph() {
		return graph;		
	}
	
	protected void setComponentListeners(GraphScene scene) {
		GraphEdgeGestures gestures = new GraphEdgeGestures(scene, this);
		gestures.addGestures();
	}
	
	public void destroy() {
		GraphNode[] nodes = this.getNodes();
		GraphNode a = nodes[0];
		GraphNode b = nodes[1];
		a.removeAdjacent(b);
		b.removeAdjacent(a);
		
	}
	
	
}
